home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / time / tolleuhr / tolleuhr_c / tolleuhr.c < prev    next >
C/C++ Source or Header  |  1994-12-07  |  44KB  |  1,357 lines

  1. #define VERSION "1.12 (7.12.94)"
  2. /***************************************************************************
  3. *                                  *                                       *
  4. * Programm: TolleUhr               * Version: s.o.                         *
  5. *                                  *                                       *
  6. ****************************************************************************
  7. *                                                                          *
  8. * Dieses Programm ist Public-Domain, d.h. wer immer Lust dazu hat, darf    *
  9. * dieses Programm kopieren, umschreiben, usw., vorausgesetzt:              *
  10. *                                                                          *
  11. * 1. Die Autorenliste bleibt voll erhalten. (auch in About-Requestern)     *
  12. * 2. Wer etwas am Programm verbricht, muß sich auch dazuschreiben.         *
  13. *                                                                          *
  14. * Es wird keine Haftung für Schäden irgendwelcher Art übernommen.          *
  15. *                                                                          *
  16. * Autor: Matthias Fleischer  Adlerstraße 30 7302 Ostfildern 2              *
  17. *        (fleischr@izfm.uni-stuttgart.de)                                  *
  18. *        .                                                                 *
  19. *        .(Auf Paul, schaff was !)                                         *
  20. *                                                                          *
  21. * changes: - NewLookMenus with Kick3.0+                                    *
  22. *          - consequent use of kickstart 2.0+ functions                    *
  23. *            ( AllocMem->AllocVec,AllocDosObject )                         *
  24. *          - bugfixed ( area-table was to small )                          *
  25. *          - openlibs() && closelibs() removed, now automatically opened   *
  26. *            and closed by startup code                                    *
  27. *          - some new local vars to enable better optimization             *
  28. *          - compiled with inline headers using gcc2.3.3 (still the best!) *
  29. *          - two versions: plain 68000 && 68020+                           *
  30. *                                                                          *
  31. *           ^ by: gnikl@informatik.uni-rostock.de                          *
  32. *                                                                          *
  33. ***************************************************************************/
  34.  
  35. /**** includes ****/
  36.  
  37. #include <dos/dos.h>
  38. #include <dos/rdargs.h>
  39. #include <exec/memory.h>
  40. #include <devices/audio.h>
  41. #include <devices/timer.h>
  42. #include <graphics/gfxmacros.h>
  43. #include <intuition/intuition.h>
  44. #include <intuition/gadgetclass.h>
  45. #include <libraries/gadtools.h>
  46. #include <workbench/startup.h>
  47. #include <workbench/workbench.h>
  48. #if defined(__GNUC__) || defined(__SASC) || defined(LATTICE)
  49. #include <proto/dos.h>
  50. #include <proto/alib.h>
  51. #include <proto/exec.h>
  52. #include <proto/icon.h>
  53. #include <proto/graphics.h>
  54. #include <proto/gadtools.h>
  55. #include <proto/intuition.h>
  56. #else
  57. #include <clib/dos_protos.h>
  58. #include <clib/alib_protos.h>
  59. #include <clib/exec_protos.h>
  60. #include <clib/icon_protos.h>
  61. #include <clib/graphics_protos.h>
  62. #include <clib/gadtools_protos.h>
  63. #include <clib/intuition_protos.h>
  64. #endif
  65.  
  66. /* workaround for inline problems */
  67.  
  68. #ifdef __GNUC__
  69. #define CreateGadgetA creategadgeta
  70. struct Gadget *CreateGadgetA();
  71. #if __GNUC_MINOR__ > 3
  72. #define AddGList addglist
  73. void AddGList();
  74. #define EasyRequestArgs easyrequestargs
  75. void EasyRequestArgs();
  76. #endif
  77. #define ALIAS(a,b) asm(".stabs \"_" #a "\",11,0,0,0\n.stabs \"_" #b "\",1,0,0,0")
  78. #endif
  79.  
  80. /* magic defines ;-( */
  81.  
  82. #define exit _exit
  83. #define main _main
  84. #define WbMsg _WBenchMsg
  85.  
  86. /* externe Symbole */
  87.  
  88. extern void exit(int);
  89. extern struct WBStartup *WbMsg;
  90.  
  91. /**** Sonstiges ****/
  92.  
  93. const char version[]="$VER:TolleUhr "VERSION" by M.Fleischer and G.Nikl in 1993/94";
  94. #define aboutstring (version+5)
  95.  
  96. typedef struct IORequest *iorequest;
  97. typedef struct timerequest *iotime;
  98. typedef struct IOAudio *ioaudio;
  99.  
  100. /**** Eigene Prototypen ****/
  101.  
  102. int main();
  103. void mergetooltypes(struct WBStartup *args);
  104. void parsecliargs(char *argstring,int laenge);
  105. int xtod(int a);
  106. void setargs(void);
  107. void setpattern(void);
  108. void readstr(char *dest,char *sorc,int n);
  109. int nexttick(void);
  110. void openall(void);
  111. void closeall(int retval);
  112. void newsize1(void); /* Löscht BitPlanes */
  113. void newsize2(void); /* Holt BitPlanes */
  114. void zifferblatt (void);
  115. void rahmen(void);
  116. void zeichnen(void);
  117. void zeiger(ULONG winkel,int lfactor,int offset,int apen,int open);
  118. void getcolor(UBYTE *color);
  119. void setalarm(void);
  120. void cdtoicon(struct WBStartup *args);
  121. void savecli();
  122. void saveprefs(char *myname);
  123. void setstr(char *dest,UBYTE *sourc,int n);
  124. int dtox(int a);
  125. void testifalarm(void);
  126. void starttune(UWORD *tune);
  127. void playnote(void);
  128. void endtune(void);
  129. struct Window *createrequest
  130. ( struct TagItem windowtags[],int anzgadgets,struct TagItem *gadgettags[],
  131.   struct NewGadget gadgets[],ULONG edge[][3],struct Gadget **glistpointer);
  132.  
  133. /**** disable commandline parsing with libnix (gcc) ****/
  134.  
  135. int __nocommandline=1;
  136.  
  137. /**** Ressourcen müssen global sein (wegen cleanup) ****/
  138.  
  139. struct Screen *pubscreen=NULL; /* Den blocken wir */
  140. struct Window *mywindow=NULL; /* 1 Fenster */
  141. struct IntuiMessage *msg; /* Für Gadgets */
  142. struct Menu *menus=NULL;
  143. APTR visi=NULL;
  144. struct MsgPort *tport=NULL; /* Timer */
  145. iotime treq=NULL;
  146. BYTE notime=1;
  147. BYTE timesent=0;
  148. char *string=NULL; /* für ToolTypes */
  149. struct DiskObject *dobj=NULL;
  150. APTR buf=NULL; /* BitPlane für Area-Befehle */
  151. struct MsgPort *audport=NULL; /* Alles für audio.device */
  152. ioaudio audreq[2]={ NULL,NULL };
  153. BYTE noaudio=1; /* device geöffnet ? */
  154. BYTE nosound=1; /* Soundkanal geholt ? */
  155. BYTE audsent[2]={ 0,0 }; /* Sound gespielt ? */
  156. BYTE *waveform=NULL;
  157. LONG oldpri; /* Task-Priority */
  158. int changedpri=0;
  159.  
  160. /**** Voreinstellungen ****/
  161.  
  162. long links =50;
  163. long oben  =50;
  164. long breite=108;
  165. long hoehe =54;
  166. int sekunden=0;
  167. int oval=0;
  168. int zeigen=1;
  169. int zeigertyp=2;
  170. int zeigerbreite=2;
  171. int schatten=0;
  172. int rahmenanz=3;
  173. UBYTE pens[]={ 2,0,2,0,2,1,2,2,2,2,0,1,2,3 };
  174.              /* sec,mina,mino,stda,stdo,shdw,12,1/4,1/12,1/60,b0,b1,b2,b3 */
  175. UBYTE must[]={ 0,0,0,0 };
  176. ULONG almin=0,alstd=12; /* Alarmzeit */
  177. int smarthour=0;
  178. int alarm=0;
  179. int chime=0;
  180. int closegad=0;
  181.  
  182. /**** Globale Variablen ****/
  183.  
  184. ULONG maskx,masky;
  185. UWORD muster[8][2];
  186. int doublex,doubley;
  187. long xoffset,yoffset;
  188. long boleft,botop,breit2,hoehe2;
  189. long hires,interlace,active=0;
  190. ULONG std,min,sec;
  191. long redrawx1,redrawx2,redrawy1,redrawy2; /* Gezeichneter Bereich bezogen
  192.                                              auf Fensterkoordinaten */
  193. struct TagItem notags[]={ TAG_DONE }; /* Leeres TagItem-Feld */
  194. struct RastPort *rport1; /* Fenster */
  195. struct BitMap abitmap; /* Buffer */
  196. struct RastPort rport2;
  197. struct TmpRas temp; /* Für Area-Befehle */
  198. struct AreaInfo info;
  199. SHORT table[13]; /* Für Area-Befehle */
  200. UWORD *playtune;
  201. struct TextAttr topaz={ "topaz.font",8,FS_NORMAL,FPF_ROMFONT };
  202.  
  203. /**** Tabellen ****/
  204.  
  205. long handwidth[]={ 4000,3250,2500,1750,1000 };
  206.  
  207. long sizes[][4]={ 0,0,3,2, -3,0,3,2, -3,-2,3,2, 0,2,0,-4 }; /* Für Gadgets */
  208.  
  209. struct Gadget gadgets[]={
  210. { &gadgets[1],0,0,1,1,GADGHNONE,
  211.   0,CLOSE,NULL,NULL,NULL,0,NULL,0,NULL },         /* Schließ-Gadget */
  212. { &gadgets[2],0,0,1,1,GADGHNONE|GRELRIGHT,
  213.   0,WUPFRONT,NULL,NULL,NULL,0,NULL,0,NULL },      /* Tiefen-Gadget */
  214. { &gadgets[3],0,0,1,1,GADGHNONE|GRELRIGHT|GRELBOTTOM,
  215.   0,SIZING,NULL,NULL,NULL,0,NULL,0,NULL },        /* Größen-Gadget */
  216. { NULL       ,0,0,1,1,GADGHNONE|GRELWIDTH|GRELHEIGHT,
  217.   0,WDRAGGING,NULL,NULL,NULL,0,NULL,0,NULL } };   /* Zieh-Gadget */
  218.  
  219. struct TagItem windowtags[]=
  220. { WA_Left,0,WA_Top,0,WA_Width,0,WA_Height,0, /* Fensterkoordinaten (s.u.) */
  221.   WA_PubScreen,0,                            /* kommt später rein */
  222.   WA_MinWidth,10,WA_MinHeight,10,WA_MaxWidth,-1,WA_MaxHeight,-1,
  223.   WA_Gadgets,(ULONG)gadgets,                 /* Liste von Gadgets */
  224.   WA_Borderless,TRUE,                        /* Rahmen mach ich selber */
  225.   WA_SimpleRefresh,TRUE,                     /* Spart CHIP-MEM */
  226.   WA_NewLookMenus,TRUE,
  227.   WA_IDCMP,NEWSIZE|CLOSEWINDOW|MENUPICK|REFRESHWINDOW|
  228.            ACTIVEWINDOW|INACTIVEWINDOW,      /* Message-Port */
  229.   WA_ScreenTitle,(ULONG)aboutstring,
  230.   TAG_DONE };
  231.  
  232. struct TagItem menutags[]=
  233. { GTMN_NewLookMenus,TRUE,TAG_DONE };
  234.  
  235. struct NewMenu menulist[]= /* Liste von Menus */
  236. { { NM_TITLE,"Project",  NULL,0,0,NULL },
  237.   { NM_ITEM, "About",    "?",0,0,NULL },
  238.   { NM_ITEM, "Save Prefs","S",0,0,NULL },
  239.   { NM_ITEM, "Quit",     "Q",0,NULL },
  240.   { NM_TITLE,"Settings", NULL,0,0,NULL },
  241.   { NM_ITEM, "Seconds",  NULL,CHECKIT|MENUTOGGLE,0,NULL },
  242.   { NM_ITEM, "Oval",     NULL,CHECKIT|MENUTOGGLE,0,NULL },
  243.   { NM_ITEM, "Show",     NULL,0,0,NULL },
  244.   { NM_SUB,  "Minutes",  NULL,CHECKIT,2|4|8|16,NULL },
  245.   { NM_SUB,  "Hours",    NULL,CHECKIT,1|4|8|16,NULL },
  246.   { NM_SUB,  "Quarter",  NULL,CHECKIT,1|2|8|16,NULL },
  247.   { NM_SUB,  "One",      NULL,CHECKIT,1|2|4|16,NULL },
  248.   { NM_SUB,  "None",     NULL,CHECKIT,1|2|4| 8,NULL },
  249.   { NM_ITEM, "Hands",    NULL,0,0,NULL },
  250.   { NM_SUB,  "Line",     NULL,CHECKIT,2|4|8,NULL },
  251.   { NM_SUB,  "Triangle", NULL,CHECKIT,1|4|8,NULL },
  252.   { NM_SUB,  "Rhombus",  NULL,CHECKIT,1|2|8,NULL },
  253.   { NM_SUB,  "Rectangle",NULL,CHECKIT,1|2|4,NULL },
  254.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  255.   { NM_SUB,  "Very Thin",NULL,CHECKIT,64|128|256|512,NULL },
  256.   { NM_SUB,  "Thin",     NULL,CHECKIT,32|128|256|512,NULL },
  257.   { NM_SUB,  "Normal",   NULL,CHECKIT,32|64|256|512,NULL },
  258.   { NM_SUB,  "Thick",    NULL,CHECKIT,32|64|128|512,NULL },
  259.   { NM_SUB,  "Very Thick",NULL,CHECKIT,32|64|128|256,NULL },
  260.   { NM_ITEM, "Shadow",   NULL,CHECKIT|MENUTOGGLE,0,NULL },
  261.   { NM_ITEM, "Border",   NULL,0,0,NULL },
  262.   { NM_SUB,  "None",     NULL,CHECKIT,2|4,NULL },
  263.   { NM_SUB,  "Single",   NULL,CHECKIT,1|4,NULL },
  264.   { NM_SUB,  "Double",   NULL,CHECKIT,1|2,NULL },
  265.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  266.   { NM_SUB,  "Hires",    NULL,CHECKIT|MENUTOGGLE,0,NULL },
  267.   { NM_SUB,  "Interlace",NULL,CHECKIT|MENUTOGGLE,0,NULL },
  268.   { NM_ITEM, "Chime",    NULL,0,0,NULL },
  269.   { NM_SUB,  "None",     NULL,CHECKIT,2|4,NULL },
  270.   { NM_SUB,  "Hours",    NULL,CHECKIT,1|4,NULL },
  271.   { NM_SUB,  "Quarter",  NULL,CHECKIT,1|2,NULL },
  272.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  273.   { NM_SUB,  "Smart",    NULL,CHECKIT|MENUTOGGLE,0,NULL },
  274.   { NM_ITEM, "Alarm",    NULL,0,0,NULL },
  275.   { NM_SUB,  "Set",      NULL,0,0,NULL },
  276.   { NM_SUB,  "On",       NULL,CHECKIT|MENUTOGGLE,0,NULL },
  277.   { NM_ITEM, "Close Gadet", NULL,CHECKIT|MENUTOGGLE,0,NULL },
  278.   { NM_TITLE,"Colors",   NULL,0,0,NULL }, /* Colours Menu */
  279.   { NM_ITEM, "Seconds",  NULL,0,0,NULL },
  280.   { NM_ITEM, "Min. APen",NULL,0,0,NULL },
  281.   { NM_ITEM, "Min. OPen",NULL,0,0,NULL },
  282.   { NM_ITEM, "Hour APen",NULL,0,0,NULL },
  283.   { NM_ITEM, "Hour OPen",NULL,0,0,NULL },
  284.   { NM_ITEM, "Shadow",   NULL,0,0,NULL },
  285.   { NM_ITEM, "12",       NULL,0,0,NULL },
  286.   { NM_ITEM, "Quarter",  NULL,0,0,NULL },
  287.   { NM_ITEM, "Hours",    NULL,0,0,NULL },
  288.   { NM_ITEM, "Minutes",  NULL,0,0,NULL },
  289.   { NM_ITEM, "Border 0", NULL,0,0,NULL },
  290.   { NM_ITEM, "Border 1", NULL,0,0,NULL },
  291.   { NM_ITEM, "Border 2", NULL,0,0,NULL },
  292.   { NM_ITEM, "Border 3", NULL,0,0,NULL },
  293.   { NM_TITLE,"Pattern",  NULL,0,0,NULL },
  294.   { NM_ITEM, "Color 0",  NULL,0,0,NULL },
  295.   { NM_ITEM, "Color 1",  NULL,0,0,NULL },
  296.   { NM_ITEM, "Color 2",  NULL,0,0,NULL },
  297.   { NM_ITEM, "Color 3",  NULL,0,0,NULL },
  298.   { NM_END,NULL,NULL,0,0,NULL } };
  299.  
  300. BYTE sinus[]= /* sinus-Tabelle */
  301. { 0,13,26,39,52,64,75,85,94,103,110,116,121,124,126,
  302.   127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
  303.   0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
  304.   -127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13 },
  305.      cosinus[]= /* cosinus-Tabelle */
  306. { 127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
  307.   0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
  308.   -127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13,
  309.   0,13,26,39,52,64,75,85,94,103,110,116,121,124,126 };
  310.  
  311. BYTE srect[]= /* Für rechteckiges Zifferblatt */
  312. { 0,13,27,41,57,73,92,111,124,127,127,127,127,127,127,
  313.   127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
  314.   0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
  315.   -127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13 },
  316.      crect[]=
  317. { 127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
  318.   0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
  319.   -127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13,
  320.   0,13,27,41,57,73,92,111,124,127,127,127,127,127,127 };
  321.  
  322. UBYTE pent[]={ 6,8,8,7,8,8,7,8,8,7,8,8 }; /* Pen-Tabelle f. Zifferblatt */
  323.  
  324. BYTE dx1[]= /* Daten für Zifferblatt */
  325. { -2, 2, 1,-2, 1, 2,-2,-2,-1,-2,-1,-2 },
  326.      dy1[]=
  327. { -4,-1,-2,-2, 2, 1,-2, 1, 2,-2,-2,-1 },
  328.      dx2[]=
  329. {  4,-2, 1, 4, 1,-2, 4, 2,-1, 4,-1, 2 },
  330.      dy2[]=
  331. {  0, 3, 2, 0,-2,-3, 0,-3,-2, 0, 2, 3 },
  332.      dx3[]=
  333. {  0,-2,-3, 0,-3,-2, 0, 2, 3, 0, 3, 2 },
  334.      dy3[]=
  335. {  8,-1, 2, 4,-2, 1, 4, 1,-2, 4, 2,-1 },
  336.      dx4[]=
  337. { -4, 2,-1,-4,-1, 2,-4,-2, 1,-4, 1,-2 },
  338.      dy4[]=
  339. {  0,-3,-2, 0, 2, 3, 0, 3, 2, 0,-2,-3 };
  340.  
  341.   /* Requester 1 */
  342. struct TagItem window2tags[]= /* Palette-Requester */
  343. { WA_Gadgets,0, /* kommen später rein */
  344.   WA_PubScreen,0, /* das auch */
  345.   WA_Left,100,WA_Top,100,WA_InnerWidth,144,WA_InnerHeight,72, /* Fensterkoordinaten */
  346.   WA_IDCMP,CLOSEWINDOW|PALETTEIDCMP,         /* Message-Port */
  347.   WA_Title,(ULONG)"Choose one:",
  348.   WA_ScreenTitle,(ULONG)aboutstring,
  349.   WA_DepthGadget,1,WA_CloseGadget,1,WA_DragBar,1,WA_Activate,1,
  350.   TAG_DONE };
  351.  
  352. ULONG window2goff[][3]=
  353. { 4,2,PALETTE_KIND };
  354.  
  355. struct NewGadget window2gad[]=
  356. { 0,0,136,68,NULL,NULL,0,0,NULL,0 };
  357.  
  358. struct TagItem window2gadtags1[]=
  359. { GTPA_Depth,0,TAG_DONE };
  360.  
  361. struct TagItem *window2gadtags[]=
  362. { window2gadtags1 };
  363.  
  364.   /* Requester 2 */
  365. struct TagItem window3tags[]= /* Alarmzeit-Requester */
  366. { WA_Gadgets,0, /* kommen später rein */
  367.   WA_PubScreen,0, /* das auch */
  368.   WA_Left,100,WA_Top,100,WA_InnerWidth,144,WA_InnerHeight,72,
  369.   WA_IDCMP,CLOSEWINDOW|BUTTONIDCMP|SLIDERIDCMP,
  370.   WA_Title,(ULONG)"Alarm",
  371.   WA_ScreenTitle,(ULONG)aboutstring,
  372.   WA_DepthGadget,1,WA_CloseGadget,1,WA_DragBar,1,WA_Activate,1,
  373.   TAG_DONE };
  374.  
  375. ULONG window3goff[][3]=
  376. { { 42,15,SLIDER_KIND },
  377.   { 82,15,SLIDER_KIND },
  378.   {  2,58,BUTTON_KIND },
  379.   { 76,58,BUTTON_KIND } };
  380.  
  381. struct NewGadget window3gad[]=
  382. { { 0,0,20,39,NULL,    &topaz,1,0,NULL,0 },
  383.   { 0,0,20,39,NULL,    &topaz,2,0,NULL,0 },
  384.   { 0,0,66,12,"Use",   &topaz,3,0,NULL,0 },
  385.   { 0,0,66,12,"Cancel",&topaz,4,0,NULL,0 } };
  386.  
  387. struct TagItem window3gadtags1[]=
  388. { GTSL_Level,1,PGA_Freedom,LORIENT_VERT,GTSL_LevelPlace,PLACETEXT_ABOVE,
  389.   GTSL_MaxLevelLen,10,GTSL_Min,1,GTSL_Max,12,GTSL_LevelFormat,
  390.   (ULONG)"%2ld",GA_RelVerify,1,TAG_DONE },
  391.                window3gadtags2[]=
  392. { GTSL_Level,0,PGA_Freedom,LORIENT_VERT,GTSL_LevelPlace,PLACETEXT_ABOVE,
  393.   GTSL_MaxLevelLen,5,GTSL_Min,0,GTSL_Max,59,GTSL_LevelFormat,
  394.   (ULONG)"%02ld",GA_RelVerify,1,TAG_DONE };
  395.  
  396. struct TagItem *window3gadtags[]=
  397. { window3gadtags1,window3gadtags2,notags,notags };
  398.  
  399. UBYTE camap[]={ 1,2,4,8 }; /* Sound Channel Allocation Map */
  400.  
  401. UWORD alarmtune[]={ 800,800,800,800,800,800,800,1600,
  402.                     800,800,800,800,800,800,800,1600,
  403.                     800,800,800,800,800,800,800,1600,
  404.                     800,800,800,800,800,800,800,1600,
  405.                     800,800,800,800,800,800,800,4,0 };
  406.  
  407. UWORD hourtune[]={ 800,1600,800,1600,800,1600,800,1600,
  408.                    800,1600,800,1600,800,1600,800,1600,
  409.                    800,1600,800,1600,800,1600,800,4,0 };
  410.  
  411. UWORD quartertune[]={ 400,400,400,400,400,4,0 };
  412.  
  413. char pattern[]=
  414. "/M,TOP/N,LEFT/N,WIDTH/N,HEIGHT/N,SECONDS/S,PATTERN/K,OVAL/S,SHADOW/S,"
  415. "SHOWFACE/N,HANDTYPE/N,HANDWIDTH/N,DRAWPENS/K,BORDERTYPE/N,CHIME/N,"
  416. "PUBSCREEN/K,TASKPRI/N,CLOSEGAD";
  417.  
  418. char *tooltypes[]={
  419. "TOP","LEFT","WIDTH","HEIGHT","SHOWFACE","HANDTYPE","HANDWIDTH","BORDERTYPE",
  420. "CHIME","SECONDS","OVAL","SHADOW","CLOSEGAD","DRAWPENS","PATTERN" };
  421.  
  422. int main()
  423. { static struct EasyStruct easyreq={
  424.     sizeof (struct EasyStruct),
  425.     0,
  426.     "About",
  427.     (UBYTE *)aboutstring,
  428.     "Ok"};
  429.   ULONG class;
  430.   UWORD code;
  431.   ULONG signals;
  432.   UWORD check;
  433.   struct MenuItem *item,*item2;
  434.   if (WbMsg) /* Start von Workbench */
  435.     mergetooltypes(WbMsg);
  436.   else
  437.     parsecliargs(NULL,0);
  438.   openall();
  439.  
  440.   nexttick();
  441.   rahmen();
  442.   zifferblatt ();
  443.   zeichnen ();
  444.   for (;;)
  445.   { signals=Wait(SIGBREAKF_CTRL_C| /* User-Break */
  446.                  1<<tport->mp_SigBit| /* Timer-Signal */
  447.                  1<<audport->mp_SigBit| /* Audio-Device */
  448.                  1<<mywindow->UserPort->mp_SigBit); /* IDCMP-Signal */
  449.     if (GetMsg(tport)) /* Timer-Signal ? */
  450.     { if (nexttick())
  451.       { zifferblatt();
  452.         testifalarm(); }
  453.       zeichnen(); }
  454.     if (GetMsg(audport)) /* Audio */
  455.       playnote();
  456.     while (msg=GT_GetIMsg(mywindow->UserPort))
  457.     { class=msg->Class;
  458.       code=msg->Code;
  459.       GT_ReplyIMsg(msg);
  460.       switch (class)
  461.       { case NEWSIZE:
  462.           newsize1();
  463.           newsize2();
  464.           rahmen();
  465.           zifferblatt ();
  466.           zeichnen ();
  467.           break;
  468.         case REFRESHWINDOW:
  469.           redrawx1=boleft;
  470.           redrawy1=botop;
  471.           redrawx2=boleft+breit2-1;
  472.           redrawy2=botop +hoehe2-1;
  473.           BeginRefresh(mywindow);
  474.           rahmen();
  475.           zeichnen();
  476.           EndRefresh(mywindow,TRUE);
  477.           break;
  478.         case MENUPICK:
  479.           while (code!=MENUNULL)
  480.           { if (!(item=ItemAddress(menus,code)))
  481.               closeall(RETURN_FAIL);
  482.             check=item->Flags&CHECKED;
  483.             switch (code)
  484.             { case FULLMENUNUM(0,0,NOSUB): /* About */
  485.                 EasyRequestArgs(mywindow,&easyreq,NULL,NULL);
  486.                 break;
  487.               case FULLMENUNUM(0,1,NOSUB): /* Save Prefs */
  488.                 if (WbMsg)
  489.                   cdtoicon(WbMsg); /* Von Workbench */
  490.                 else
  491.                   savecli(); /* Von CLI */
  492.                 break;
  493.               case FULLMENUNUM(0,2,NOSUB): /* Quit */
  494.                 closeall(RETURN_OK);
  495.               case FULLMENUNUM(1,0,NOSUB): /* Menu Seconds ausgewählt */
  496.                 sekunden=check;
  497.                 if (timesent)
  498.                 { AbortIO((iorequest)treq);
  499.                   WaitIO((iorequest)treq);
  500.                   timesent=0; }
  501.                 nexttick();
  502.                 break;
  503.               case FULLMENUNUM(1,1,NOSUB): /* oval umschalten */
  504.                 oval=check;
  505.                 break;
  506.               case FULLMENUNUM(1,2,0): /* zifferblatt */
  507.               case FULLMENUNUM(1,2,1):
  508.               case FULLMENUNUM(1,2,2):
  509.               case FULLMENUNUM(1,2,3):
  510.               case FULLMENUNUM(1,2,4):
  511.                 if (check)
  512.                   zeigen=SUBNUM(code);
  513.                 break;
  514.               case FULLMENUNUM(1,3,0): /* zeiger */
  515.               case FULLMENUNUM(1,3,1):
  516.               case FULLMENUNUM(1,3,2):
  517.               case FULLMENUNUM(1,3,3):
  518.                 if (check)
  519.                   zeigertyp=SUBNUM(code);
  520.                 break;
  521.               case FULLMENUNUM(1,3,5): /* zeigerbreite */
  522.               case FULLMENUNUM(1,3,6):
  523.               case FULLMENUNUM(1,3,7):
  524.               case FULLMENUNUM(1,3,8):
  525.               case FULLMENUNUM(1,3,9):
  526.                 if (check)
  527.                   zeigerbreite=SUBNUM(code)-5;
  528.                 break;
  529.               case FULLMENUNUM(1,4,NOSUB): /* Shadow */
  530.                 schatten=check;
  531.                 break;
  532.               case FULLMENUNUM(1,5,0): /* Rahmen */
  533.               case FULLMENUNUM(1,5,1):
  534.               case FULLMENUNUM(1,5,2):
  535.                 if (check)
  536.                   rahmenanz=SUBNUM(code);
  537.                 break;
  538.               case FULLMENUNUM(1,5,4):
  539.                 hires=check;
  540.                 break;
  541.               case FULLMENUNUM(1,5,5):
  542.                 interlace=check;
  543.                 break;
  544.               case FULLMENUNUM(1,6,0): /* Chime */
  545.               case FULLMENUNUM(1,6,1):
  546.               case FULLMENUNUM(1,6,2):
  547.                 if (check)
  548.                   chime=SUBNUM(code);
  549.                 break;
  550.               case FULLMENUNUM(1,6,4):
  551.                 smarthour=check;
  552.                 break;
  553.               case FULLMENUNUM(1,7,0): /* Alarm set */
  554.                 setalarm();
  555.                 item2=ItemAddress(menus,FULLMENUNUM(1,7,1));
  556.                 ClearMenuStrip(mywindow); /* Menu entfernen */
  557.                 item2->Flags&=~CHECKED;    /* Flags anpassen */
  558.                 if (alarm)
  559.                   item2->Flags|=CHECKED;
  560.                 ResetMenuStrip(mywindow,menus); /* Menu wieder einfügen */
  561.                 break;
  562.               case FULLMENUNUM(1,7,1):
  563.                 alarm=check;
  564.                 break;
  565.               case FULLMENUNUM(1,8,NOSUB):
  566.                 closegad=check;
  567.                 break;
  568.               default:
  569.                 if (MENUNUM(code)==2)
  570.                 { getcolor(&pens[ITEMNUM(code)]);
  571.                   break; }
  572.                 if (MENUNUM(code)==3)
  573.                 { getcolor(&must[ITEMNUM(code)]);
  574.                   setpattern();
  575.                   break; }
  576.                 break;
  577.             } /* switch menus */
  578.             code=item->NextSelect;
  579.           } /* while */
  580.           newsize1(); /* Zwar manchmal unnötig, aber kurz */
  581.           newsize2();
  582.           rahmen();
  583.           zifferblatt();
  584.           zeichnen();
  585.           break;
  586.         case ACTIVEWINDOW:
  587.           active=1;
  588.           rahmen();
  589.           break;
  590.         case INACTIVEWINDOW:
  591.           active=0;
  592.           rahmen();
  593.           break;
  594.         case CLOSEWINDOW:
  595.           if (closegad)
  596.             closeall(RETURN_OK);
  597.       } /* switch*/
  598.     } /* if */
  599.     if (signals&SIGBREAKF_CTRL_C) /* User-Break */
  600.       closeall(RETURN_WARN);
  601.   } /* for */
  602. } /* main */
  603.  
  604. void mergetooltypes(struct WBStartup *args)
  605. { BPTR oldlock;
  606.   char *newmem;
  607.   char **ttypes;
  608.   ULONG strln=1;
  609.   int i,k;
  610.  
  611.   if (!args->sm_ArgList) /* Was da wohl für eine Arglist dahintersteckt ? */
  612.     return;
  613.   oldlock=CurrentDir(args->sm_ArgList->wa_Lock); /* CD */
  614.   dobj=GetDiskObject(args->sm_ArgList->wa_Name);
  615.   CurrentDir(oldlock);
  616.   if (!dobj)
  617.     closeall(RETURN_FAIL);
  618.   ttypes=dobj->do_ToolTypes;
  619.   if (!(string=AllocVec(strln,MEMF_ANY|MEMF_CLEAR)))
  620.     closeall(RETURN_FAIL);
  621.   for (i=0;ttypes[i];i++)
  622.   { for (k=0;ttypes[i][k];k++) /* Länge ermitteln */
  623.       ;
  624.     if (!(newmem=AllocVec(strln+k+1,MEMF_ANY|MEMF_CLEAR))) /* Neuer String */
  625.       closeall(RETURN_FAIL);
  626.     sprintf(newmem,"%s %s",string,ttypes[i]);
  627.     FreeVec(string);
  628.     string=newmem;
  629.     strln+=k+1;
  630.   } /* for */
  631.   FreeDiskObject(dobj); dobj=NULL;
  632.   parsecliargs(string,strln-1);
  633.   FreeVec(string);
  634.   string=NULL;
  635. } /* mergetooltypes */
  636.  
  637. void parsecliargs(char *argstring,int laenge)
  638.   struct RDArgs *rdarg,*args;
  639.   ULONG ergebnis[20],*erg,*e;
  640.  
  641.   if (!(rdarg=AllocDosObject(DOS_RDARGS,NULL)))
  642.     closeall(RETURN_FAIL);
  643.   rdarg->RDA_Source.CS_Buffer=argstring;
  644.   rdarg->RDA_Source.CS_Length=laenge;
  645.   e=&ergebnis[0]; do { *e++=0; } while (&ergebnis[20]>e);
  646.   args=ReadArgs(argstring?pattern:&pattern[3],ergebnis,rdarg);
  647.   if (!argstring && !args) /* Fehler in der Kommandozeile */
  648.   {
  649.     FreeDosObject(DOS_RDARGS,rdarg);
  650.     closeall(RETURN_FAIL);
  651.   }
  652.   erg=(argstring?&ergebnis[1]:ergebnis);
  653.   if (erg[0])
  654.     oben  =*(LONG *)erg[0];
  655.   if (erg[1])
  656.     links =*(LONG *)erg[1];
  657.   if (erg[2])
  658.     breite=*(LONG *)erg[2];
  659.   if (erg[3])
  660.     hoehe =*(LONG *)erg[3];
  661.   if (erg[4])
  662.     sekunden=1;
  663.   if (erg[5])
  664.     readstr(must,(char *)erg[5],4);
  665.   if (erg[6])
  666.     oval=1;
  667.   if (erg[7])
  668.     schatten=1;
  669.   if (erg[8])
  670.     zeigen=*(LONG *)erg[8];
  671.   if (erg[9])
  672.     zeigertyp=*(LONG *)erg[9];
  673.   if (erg[10])
  674.     zeigerbreite=*(LONG *)erg[10];
  675.   if (erg[11])
  676.     readstr(pens,(char *)erg[11],14);
  677.   if (erg[12])
  678.     rahmenanz=*(LONG *)erg[12];
  679.   if (erg[13])
  680.     chime=*(LONG *)erg[13];
  681.   pubscreen=LockPubScreen((char *)erg[14]); /* 0 gibt Default-PubScreen */
  682.   if (erg[15])
  683.   { oldpri=SetTaskPri(FindTask(NULL),*(LONG *)erg[15]);
  684.     changedpri=1; }
  685.   if (erg[16])
  686.     closegad=1;
  687.   FreeArgs(args);
  688.   FreeDosObject(DOS_RDARGS,rdarg);
  689.   setargs();
  690. } /* parsecliargs */
  691.  
  692. void readstr(char *dest,char *sorc,int n)
  693. { if (*sorc=='x'||*sorc=='X') /* Hexadezimal */
  694.     while (n-- && *sorc++ && *sorc++)
  695.       *dest++=(xtod(sorc[-1])<<4)+xtod(*sorc);
  696.   else
  697.     while (*sorc && n--) /* Dezimal */
  698.       *dest++=xtod(*sorc++);
  699. } /* readstr */
  700.  
  701. int xtod(int a)
  702. { if (a>='0' && a<='9')
  703.     return(a-'0');
  704.   if (a>='a' && a<='f')
  705.     return(a-'a'+10);
  706.   if (a>='A' && a<='F')
  707.     return(a-'A'+10);
  708.   return(0);
  709. } /* xtod */
  710.  
  711. void setargs(void)
  712. { if (breite<10)/* Zu schmal ? */
  713.     breite=10;
  714.   if (hoehe<10)
  715.     hoehe=10;
  716.   if (zeigen<0 || zeigen>4)
  717.     zeigen=0;
  718.   if (zeigertyp<0 || zeigertyp>3)
  719.     zeigertyp=0;
  720.   if (zeigerbreite<0 || zeigerbreite>4)
  721.     zeigerbreite=0;
  722.   if (rahmenanz<0 || rahmenanz>5)
  723.     rahmenanz=0;
  724.   if (chime<0 || chime>5)
  725.     chime=0;
  726.   if (chime>2)
  727.   { chime-=3;
  728.     smarthour=1; }
  729.   if (rahmenanz>2)
  730.   { hires=rahmenanz&1;
  731.     interlace=rahmenanz>3;
  732.     rahmenanz=2; }
  733.   setpattern();
  734. } /* setargs */
  735.  
  736. void setpattern(void)
  737. { int i,a,b,c,d;
  738.   UBYTE *p1;
  739.   UWORD *p2;
  740.  
  741.   p1=must; a=*p1++; b=*p1++; c=*p1++; d=*p1;
  742.   if (a==b && c==d) /* nur horizontale Streifen */
  743.     maskx=0xffffffff;
  744.   else
  745.     maskx=0xfffffffe;
  746.   if (a==c && b==d) /* nur vertikale Streifen */
  747.     masky=0xffffffff;
  748.   else
  749.     masky=0xfffffffe;
  750.   p2=(UWORD *)muster;
  751.   for (i=0;i<8;i++)
  752.   { *p2=(a&1<<i?0x5555:0)|(b&1<<i?0xaaaa:0); p2++;
  753.     *p2=(c&1<<i?0x5555:0)|(d&1<<i?0xaaaa:0); p2++; }
  754. } /* setpattern */
  755.  
  756. int nexttick(void)
  757. { ULONG oldmin;
  758.   treq->tr_node.io_Command=TR_GETSYSTIME;
  759.   DoIO((iorequest)treq);/* Zeit besorgen */
  760.   treq->tr_time.tv_micro=1100000-treq->tr_time.tv_micro;
  761.   sec=treq->tr_time.tv_secs; /* ^ Ein ganz besonders netter Effekt: Das Timerdevice */
  762.   treq->tr_time.tv_secs=(sekunden?0:59-sec%60); /* rundet aktuelle Zeit und Wartezeit ab */
  763.   treq->tr_node.io_Command=TR_ADDREQUEST;
  764.   SendIO((iorequest)treq); /* Und abschicken */
  765.   oldmin=min;
  766.   min=sec/60;
  767.   sec=sec%60;
  768.   std=min/12;
  769.   min=min%60;
  770.   std=std%60;
  771.   timesent=-1;
  772.   return (min-oldmin); /* sec==0 ist unzuverlässig bei hoher CPU-Auslastung */
  773. } /* nexttick */
  774.  
  775. void openall(void)
  776.   /* Libraries sind schon geöffnet, PubScreen schon blockiert */
  777.  
  778.   if (tport=CreateMsgPort()) /* Port für Timer */
  779.     if (treq=CreateIORequest(tport,sizeof(struct timerequest)))
  780.       if (!(notime=OpenDevice(TIMERNAME,UNIT_VBLANK,(iorequest)treq,0)))
  781.         if (audport=CreateMsgPort()) /* Replyport für audio.device */
  782.           if (audreq[0]=CreateIORequest(audport,sizeof(struct IOAudio)))
  783.             if (audreq[1]=CreateIORequest(audport,sizeof(struct IOAudio)))
  784.               if (!(noaudio=OpenDevice(AUDIONAME,0,(iorequest)audreq[0],0)))
  785.                 if (waveform=AllocMem(8,MEMF_CHIP|MEMF_CLEAR))
  786.                 {
  787.                   ((LONG *)waveform)[0]=0x7f807f80; /* Rechteck */
  788.                   if (visi=GetVisualInfoA(pubscreen,NULL))
  789.                   {
  790.                     if (sekunden)
  791.                       menulist[5].nm_Flags|=CHECKED;
  792.                     if (oval)
  793.                       menulist[6].nm_Flags|=CHECKED;
  794.                     if (schatten)
  795.                       menulist[24].nm_Flags|=CHECKED;
  796.                     if (hires)
  797.                       menulist[30].nm_Flags|=CHECKED;
  798.                     if (interlace)
  799.                       menulist[31].nm_Flags|=CHECKED;
  800.                     if (smarthour)
  801.                       menulist[37].nm_Flags|=CHECKED;
  802.                     if (closegad)
  803.                       menulist[41].nm_Flags|=CHECKED;
  804.                     menulist[8+zeigen].nm_Flags|=CHECKED;
  805.                     menulist[14+zeigertyp].nm_Flags|=CHECKED;
  806.                     menulist[19+zeigerbreite].nm_Flags|=CHECKED;
  807.                     menulist[26+rahmenanz].nm_Flags|=CHECKED;
  808.                     menulist[33+chime].nm_Flags|=CHECKED;
  809.                     if (menus=CreateMenusA(menulist,NULL))
  810.                       if (LayoutMenusA(menus,visi,menutags))
  811.                       {
  812.                         windowtags[0].ti_Data=links;
  813.                         windowtags[1].ti_Data=oben;
  814.                         windowtags[2].ti_Data=breite;
  815.                         windowtags[3].ti_Data=hoehe;
  816.                         windowtags[4].ti_Data=(ULONG)pubscreen;
  817.                         if (mywindow=OpenWindowTagList(NULL,windowtags))
  818.                         {
  819.                           SetMenuStrip(mywindow,menus);
  820.                           rport1=mywindow->RPort;
  821.                           SetAPen(rport1,pens[0]);
  822.                           newsize2();
  823.                           return;
  824.                         }
  825.                       }
  826.                   }
  827.                 }
  828.   closeall(RETURN_FAIL);
  829. } /* openall */
  830.                     
  831. void closeall(int retval) /* Aufräumen */
  832. { newsize1(); /* Bitmaps löschen */
  833.   if (string)
  834.     FreeVec(string);
  835.   if (dobj)
  836.     FreeDiskObject(dobj);
  837.   if (mywindow) /* Window schließen */
  838.   { ClearMenuStrip(mywindow);
  839.     CloseWindow(mywindow); }
  840.   if (menus)
  841.     FreeMenus(menus);
  842.   if (visi)
  843.     FreeVisualInfo(visi);
  844.   if (pubscreen)
  845.     UnlockPubScreen(NULL,pubscreen);
  846.   if (waveform)
  847.     FreeMem(waveform,8);
  848.   if (audsent[0])
  849.   { AbortIO((iorequest)audreq[0]); /* Ton abbrechen */
  850.     WaitIO((iorequest)audreq[0]); }
  851.   if (audsent[1])
  852.   { AbortIO((iorequest)audreq[1]); /* Ton abbrechen */
  853.     WaitIO((iorequest)audreq[1]); }
  854.   if (!nosound)
  855.     endtune();
  856.   if (!noaudio)
  857.     CloseDevice((iorequest)audreq[0]);
  858.   if (audreq[1])
  859.     DeleteIORequest(audreq[1]);
  860.   if (audreq[0])
  861.     DeleteIORequest(audreq[0]);
  862.   if (audport)
  863.     DeleteMsgPort(audport);
  864.   if (timesent)
  865.   { AbortIO((iorequest)treq);
  866.     WaitIO((iorequest)treq); }
  867.   if (!notime) /* Timerequest abbrechen */
  868.     CloseDevice((iorequest)treq);
  869.   if (treq)
  870.     DeleteIORequest(treq);
  871.   if (tport)
  872.     DeleteMsgPort(tport);
  873.   if (changedpri)
  874.     SetTaskPri(FindTask(NULL),oldpri);
  875.   exit(retval); /* Fertig */
  876. } /* closeall */
  877.  
  878. void newsize2(void) /* Holt BitPlanes */
  879. { int i,k;
  880.   static long gadgsize=-1;
  881.   long newsize;
  882.   boleft=rahmenanz+(hires    ?(rahmenanz==2)<<1:0);
  883.   botop =rahmenanz+(interlace?(rahmenanz==2)<<1:0);
  884.   breite=mywindow->Width;
  885.   hoehe =mywindow->Height;
  886.   breit2=breite-(boleft<<1);
  887.   hoehe2=hoehe -(botop <<1);
  888.   doublex=(maskx==-2&&breit2>12);
  889.   doubley=(masky==-2&&hoehe2>12);
  890.   xoffset=(breit2>50?2:(breit2>25?1:0));
  891.   yoffset=(hoehe2>50?2:(hoehe2>25?1:0));
  892.   newsize=(breite<hoehe?breite/8:hoehe/8);
  893.   if (newsize!=gadgsize)
  894.   { gadgsize=newsize; /* Gadgets müssen in der Größe angepasst werden */
  895.     RemoveGList(mywindow,gadgets,-1);
  896.     for (i=0;i<4;i++)
  897.       for (k=0;k<4;k++) /* Casting ist nicht schön, aber wirksam */
  898.         ((SHORT *)&gadgets[i].LeftEdge)[k]=sizes[i][k]*gadgsize;
  899.     AddGList(mywindow,gadgets,0,4,NULL);
  900.   } /* if */
  901.   InitBitMap(&abitmap,mywindow->WScreen->BitMap.Depth,breit2,hoehe2);
  902.   for (i=0;i<abitmap.Depth;i++)
  903.     if (!(abitmap.Planes[i]=AllocRaster(breit2,hoehe2)))
  904.       closeall(RETURN_FAIL);
  905.   InitRastPort(&rport2);
  906.   rport2.BitMap=&abitmap;
  907.   if (!(buf=AllocRaster(breit2,hoehe2)))
  908.     closeall(RETURN_FAIL);
  909.   rport2.TmpRas=InitTmpRas (&temp,buf,RASSIZE(breit2,hoehe2));
  910.   InitArea (&info,table,5);
  911.   rport2.AreaInfo=(struct AreaInfo *)&info;
  912. } /* newsize2 */
  913.  
  914. void newsize1(void) /* Löscht BitPlanes */
  915. { int i;
  916.   if (buf)
  917.   { FreeRaster(buf,breit2,hoehe2);
  918.     buf=NULL; }
  919.   for (i=0;i<abitmap.Depth;i++)
  920.   if (abitmap.Planes[i])
  921.   { FreeRaster(abitmap.Planes[i],breit2,hoehe2);
  922.     abitmap.Planes[i]=NULL; }
  923. } /* newsize1 */
  924.  
  925. void zifferblatt (void)
  926. { int i,a,b,c;
  927.   long x0,y0,x,y;
  928.  
  929.   BNDRYOFF (&rport2); /* Hintergrund */
  930.   SetAPen  (&rport2,-1);
  931.   SetAfPt  (&rport2,*muster,-1);
  932.   RectFill (&rport2,0,0,breit2-1,hoehe2-1);
  933.   SetAfPt  (&rport2,0,0);
  934.  
  935.   x0=breit2/2;
  936.   y0=hoehe2/2;
  937.  
  938.   a=(zeigen>1?(zeigen==3?60:15):(zeigen?5:1));
  939.   if (zeigen<4)
  940.     for (i=0;i<60;i+=a)
  941.     { x=x0+((oval?  sinus[i]:srect[i])*breit2/300)&maskx;/* Position des Striches */
  942.       y=y0-((oval?cosinus[i]:crect[i])*hoehe2/300)&masky;
  943.       if (i%5)
  944.       { if (i%5==1)
  945.         { c=pens[9];
  946.           SetAPen(&rport2,c);
  947.           SetOPen(&rport2,c); }
  948.         AreaMove (&rport2,x+breit2/200,y);
  949.         AreaDraw (&rport2,x,y+hoehe2/200);
  950.         AreaDraw (&rport2,x-breit2/200,y);
  951.         AreaDraw (&rport2,x,y-hoehe2/200);
  952.         AreaEnd  (&rport2);
  953.       } else
  954.       { b=i/5;
  955.         c=pens[pent[b]];
  956.         SetAPen(&rport2,c);
  957.         SetOPen(&rport2,c);
  958.         AreaMove (&rport2,x+=breit2*dx1[b]/100,y+=hoehe2*dy1[b]/100);
  959.         AreaDraw (&rport2,x+=breit2*dx2[b]/100,y+=hoehe2*dy2[b]/100);
  960.         AreaDraw (&rport2,x+=breit2*dx3[b]/100,y+=hoehe2*dy3[b]/100);
  961.         AreaDraw (&rport2,x+=breit2*dx4[b]/100,y+=hoehe2*dy4[b]/100);
  962.         AreaEnd  (&rport2);
  963.       } /* if */
  964.     } /* for */
  965.   if (schatten)
  966.   { zeiger(std,440,1,pens[5],pens[5]);
  967.     zeiger(min,300,1,pens[5],pens[5]); }
  968.   zeiger(std,440,0,pens[3],pens[4]);
  969.   zeiger(min,300,0,pens[1],pens[2]);
  970.  
  971.   redrawx1=boleft;
  972.   redrawy1=botop;
  973.   redrawx2=boleft+breit2-1;
  974.   redrawy2=botop +hoehe2-1;
  975. } /* zifferblatt */
  976.  
  977. void rahmen(void)
  978. { if (rahmenanz)
  979.   { SetAPen(rport1,(active&&rahmenanz==1)?pens[12]:pens[11]);
  980.     Move(rport1,1            ,hoehe-1    );
  981.     Draw(rport1,breite-1     ,hoehe-1    );
  982.     Draw(rport1,breite-1     ,1          );
  983.     SetAPen(rport1,(active&&rahmenanz==1)?pens[11]:pens[12]);
  984.     Move(rport1,0,            hoehe-1    );
  985.     Draw(rport1,0,            0          );
  986.     Draw(rport1,breite-1,     0          );
  987.     if (rahmenanz==2)
  988.     { SetAPen(rport1,pens[12]); /* Rahmen */
  989.       Move(rport1,boleft       ,hoehe-botop);
  990.       Draw(rport1,breite-boleft,hoehe-botop);
  991.       Draw(rport1,breite-boleft,botop      );
  992.       SetAPen(rport1,pens[11]);
  993.       Move(rport1,boleft-1     ,hoehe-botop);
  994.       Draw(rport1,boleft-1     ,botop-1    );
  995.       Draw(rport1,breite-boleft,botop-1    );
  996.       SetAPen(rport1,active?pens[13]:pens[10]);
  997.       if (hires)
  998.       { RectFill(rport1,1,1,2,hoehe-2);
  999.         RectFill(rport1,breite-3,1,breite-2,hoehe-2); }
  1000.       if (interlace)
  1001.       { RectFill(rport1,1,1,breite-2,2);
  1002.         RectFill(rport1,1,hoehe-3,breite-2,hoehe-2); }
  1003.     } /* if */
  1004.   } /* if */
  1005.   SetAPen(rport1,pens[0]);
  1006. } /* rahmen */
  1007.  
  1008. void zeiger(ULONG winkel,int lfactor,int offset,int apen,int open)
  1009. { long x0,y0,x1,y1,x2,y2;
  1010.   x0=breit2/2+(offset?xoffset:0);
  1011.   y0=hoehe2/2+(offset?yoffset:0);
  1012.   x2=sinus  [winkel]*breit2/lfactor;
  1013.   y2=cosinus[winkel]*hoehe2/lfactor;
  1014.   x1=cosinus[winkel]*breit2/handwidth[zeigerbreite];
  1015.   y1=sinus  [winkel]*hoehe2/handwidth[zeigerbreite];
  1016.   SetAPen(&rport2,apen);
  1017.   SetOPen(&rport2,open);
  1018.   switch (zeigertyp)
  1019.   { case 0:
  1020.       SetAPen(&rport2,open);
  1021.       Move (&rport2,x0,y0);
  1022.       Draw (&rport2,x0+x2,y0-y2);
  1023.       if (doublex)
  1024.       { Move (&rport2,1+x0,y0);
  1025.         Draw (&rport2,1+x0+x2,y0-y2); }
  1026.       if (doubley)
  1027.       { Move (&rport2,x0,1+y0);
  1028.         Draw (&rport2,x0+x2,1+y0-y2); }
  1029.       break;
  1030.     case 1:
  1031.       AreaMove (&rport2,x0+x2     ,y0-y2     );
  1032.       AreaDraw (&rport2,x0+x1-x2/4,y0+y1+y2/4);
  1033.       AreaDraw (&rport2,x0-x1-x2/4,y0-y1+y2/4);
  1034.       AreaEnd  (&rport2);
  1035.       break;
  1036.     case 2:
  1037.       AreaMove (&rport2,x0+x2  ,y0-y2  );
  1038.       AreaDraw (&rport2,x0+x1  ,y0+y1  );
  1039.       AreaDraw (&rport2,x0-x2/4,y0+y2/4);
  1040.       AreaDraw (&rport2,x0-x1  ,y0-y1  );
  1041.       AreaEnd  (&rport2);
  1042.       break;
  1043.     case 3:
  1044.       AreaMove (&rport2,x0+=x2-x1/2,y0-=y2+y1/2);
  1045.       AreaDraw (&rport2,x0+=x1     ,y0+=y1     );
  1046.       AreaDraw (&rport2,x0-=x2*5/4 ,y0+=y2*5/4 );
  1047.       AreaDraw (&rport2,x0-=x1     ,y0-=y1     );
  1048.       AreaEnd  (&rport2);
  1049.       break;
  1050.   } /* switch */
  1051. } /* zeiger */
  1052.  
  1053. void zeichnen(void)
  1054. { long tmp;
  1055.   BltBitMapRastPort(&abitmap,redrawx1-boleft,redrawy1-botop,
  1056.                     rport1,redrawx1,redrawy1,
  1057.                     redrawx2-redrawx1+1,redrawy2-redrawy1+1,0xc0);
  1058.   if (sekunden)
  1059.   { redrawx1=breite/2;
  1060.     redrawy1=hoehe /2;
  1061.     redrawx2=redrawx1+sinus  [sec]*breit2/300;
  1062.     redrawy2=redrawy1-cosinus[sec]*hoehe2/300;
  1063.     Move(rport1,redrawx1,redrawy1);
  1064.     Draw(rport1,redrawx2,redrawy2);
  1065.     if (doublex)
  1066.     { Move(rport1,1+redrawx1,redrawy1);
  1067.       Draw(rport1,1+redrawx2,redrawy2); }
  1068.     if (doubley)
  1069.     { Move(rport1,redrawx1,1+redrawy1);
  1070.       Draw(rport1,redrawx2,1+redrawy2); }
  1071.     if (redrawx1>redrawx2)
  1072.     { tmp=redrawx1;
  1073.       redrawx1=redrawx2;
  1074.       redrawx2=tmp; }
  1075.     if (redrawy1>redrawy2)
  1076.     { tmp=redrawy1;
  1077.       redrawy1=redrawy2;
  1078.       redrawy2=tmp; }
  1079.     if (doublex)
  1080.       redrawx2++;
  1081.     if (doubley)
  1082.       redrawy2++;
  1083.   } /* if */
  1084. } /* zeichnen */
  1085.  
  1086. void getcolor(UBYTE *color)
  1087. { struct Window *window;
  1088.   struct Gadget *gadgets;
  1089.   struct IntuiMessage *msg;
  1090.   window2gadtags1[0].ti_Data=abitmap.Depth;
  1091.   if (window=createrequest(window2tags,1,window2gadtags,window2gad,window2goff,&gadgets))
  1092.   { WaitPort(window->UserPort);
  1093.     msg=GT_GetIMsg(window->UserPort);
  1094.     if (msg->Class==GADGETUP) /* kann nur das Palette-Gadget sein */
  1095.       *color=msg->Code;
  1096.     GT_ReplyIMsg(msg);
  1097.     CloseWindow(window);
  1098.   } /* if */
  1099.   FreeGadgets(gadgets);
  1100. } /* getcolor */
  1101.  
  1102. void setalarm(void)
  1103. { struct Window *window;
  1104.   struct Gadget *gadgets;
  1105.   struct IntuiMessage *msg;
  1106.   ULONG class,st,mi;
  1107.   st=window3gadtags1[0].ti_Data=alstd;
  1108.   mi=window3gadtags2[0].ti_Data=almin;
  1109.   if (window=createrequest(window3tags,4,window3gadtags,window3gad,window3goff,&gadgets))
  1110.   { do
  1111.     { WaitPort(window->UserPort);
  1112.       msg=GT_GetIMsg(window->UserPort);
  1113.       class=msg->Class;
  1114.       if (class==MOUSEMOVE || class==GADGETUP)
  1115.       { switch(((struct Gadget *)(msg->IAddress))->GadgetID)
  1116.         { case 1:
  1117.             st=msg->Code;
  1118.             break;
  1119.           case 2:
  1120.             mi=msg->Code;
  1121.             break;
  1122.           case 3:
  1123.             alstd=st;
  1124.             almin=mi;
  1125.             alarm=1;
  1126.             class=CLOSEWINDOW;
  1127.             break;
  1128.           case 4:
  1129.             class=CLOSEWINDOW;
  1130.             break;
  1131.         } /* switch */
  1132.       } /* if */
  1133.       GT_ReplyIMsg(msg);
  1134.     } while (class!=CLOSEWINDOW);
  1135.     CloseWindow(window);
  1136.   } /* if */
  1137.   FreeGadgets(gadgets);
  1138. } /* getcolor */
  1139.  
  1140. struct Window *createrequest
  1141. ( struct TagItem windowtags[],int anzgadgets,struct TagItem *gadgettags[],
  1142.   struct NewGadget gadgets[],ULONG edge[][3],struct Gadget **glistpointer)
  1143. { struct Gadget *context;
  1144.   struct Window *window;
  1145.   int i;
  1146.   *glistpointer=NULL;
  1147.   if (context=CreateContext(glistpointer))
  1148.   { for (i=0;i<anzgadgets;i++)
  1149.     { gadgets[i].ng_LeftEdge=edge[i][0]+  mywindow->WScreen->WBorLeft;
  1150.       gadgets[i].ng_TopEdge =edge[i][1]+1+mywindow->WScreen->WBorTop+
  1151.                                         mywindow->WScreen->RastPort.TxHeight;
  1152.       gadgets[i].ng_VisualInfo=visi;
  1153.       if (!(context=CreateGadgetA(edge[i][2],context,&gadgets[i],gadgettags[i])))
  1154.         break;
  1155.     } /* for */
  1156.     if (i==anzgadgets)
  1157.     { windowtags[0].ti_Data=(ULONG)*glistpointer;
  1158.       windowtags[1].ti_Data=(ULONG)pubscreen;
  1159.       if (window=OpenWindowTagList(NULL,windowtags))
  1160.       { GT_RefreshWindow(window,NULL);
  1161.         return(window); }
  1162.     } /* if */
  1163.     if (*glistpointer)
  1164.       FreeGadgets(*glistpointer);
  1165.   } /* if */
  1166.   return(NULL);
  1167. } /* createrequest */
  1168.  
  1169. void cdtoicon(struct WBStartup *args)
  1170. { BPTR oldlock;
  1171.   if (!args->sm_ArgList) /* Was da wohl für eine Arglist dahintersteckt ? */
  1172.     return;
  1173.   oldlock=CurrentDir(args->sm_ArgList->wa_Lock); /* CD */
  1174.   saveprefs(args->sm_ArgList->wa_Name);
  1175.   CurrentDir(oldlock);
  1176. } /* cdtoicon */
  1177.  
  1178. void savecli()
  1179. { char *buffer;
  1180.   if (buffer=AllocVec(120,MEMF_ANY)) /* should be enough */
  1181.   {
  1182.     if (GetProgramName(buffer,120))
  1183.       saveprefs(buffer);
  1184.     FreeVec(buffer);
  1185.   }
  1186. } /* savecli */
  1187.  
  1188.  
  1189. void saveprefs(char *myname)
  1190. {
  1191.   if (dobj=GetDiskObjectNew(myname)) /* Tooltypes einlesen */
  1192.   { 
  1193.     UBYTE **ttypes,**p1,**p2,*tbuf,*tbuf1,*p;
  1194.     int i;
  1195.  
  1196.     p1=(UBYTE **)dobj->do_ToolTypes; p2=p1; do {} while(*p2++) ;
  1197.  
  1198.     if ((tbuf=AllocVec(((UBYTE *)p2-(UBYTE *)p1)+sizeof(tooltypes)+40*sizeof(tooltypes)/sizeof(char *),MEMF_ANY|MEMF_CLEAR)))
  1199.     {
  1200.       (UBYTE *)ttypes=tbuf+40*sizeof(tooltypes)/sizeof(char *);
  1201.  
  1202.       p1=(UBYTE **)dobj->do_ToolTypes; p2=ttypes; do {} while(*p2++=*p1++) ;
  1203.  
  1204.       for (i=0;i<sizeof(tooltypes)/sizeof(char *);i++) /* Eigene Tooltypes */
  1205.       { if (FindToolType(ttypes,tooltypes[i]))         /* entfernen */
  1206.         { p2=ttypes;
  1207.           do {} while(*++p2 && FindToolType(p2,tooltypes[i]));
  1208.           do { p=*p2++; } while(p2[-2]=p);
  1209.         }
  1210.       } /* for */
  1211.  
  1212.       /* Tooltypes zählen */
  1213.       p2=ttypes; do {} while(*p2++) ; --p2; tbuf1=tbuf;
  1214.  
  1215.       sprintf(tbuf1,"%s=%ld",tooltypes[0],mywindow->TopEdge);
  1216.       *p2++=tbuf1; tbuf1+=40;
  1217.       sprintf(tbuf1,"%s=%ld",tooltypes[1],mywindow->LeftEdge);
  1218.       *p2++=tbuf1; tbuf1+=40;
  1219.       sprintf(tbuf1,"%s=%ld",tooltypes[2],breite);
  1220.       *p2++=tbuf1; tbuf1+=40;
  1221.       sprintf(tbuf1,"%s=%ld",tooltypes[3],hoehe);
  1222.       *p2++=tbuf1; tbuf1+=40;
  1223.       sprintf(tbuf1,"%s=%ld",tooltypes[4],zeigen);
  1224.       *p2++=tbuf1; tbuf1+=40;
  1225.       sprintf(tbuf1,"%s=%ld",tooltypes[5],zeigertyp);
  1226.       *p2++=tbuf1; tbuf1+=40;
  1227.       sprintf(tbuf1,"%s=%ld",tooltypes[6],zeigerbreite);
  1228.       *p2++=tbuf1; tbuf1+=40;
  1229.       sprintf(tbuf1,"%s=%ld",tooltypes[7],
  1230.         rahmenanz+(rahmenanz==2?(hires?1:0)+(interlace?2:0):0));
  1231.       *p2++=tbuf1; tbuf1+=40;
  1232.       sprintf(tbuf1,"%s=%ld",tooltypes[8],chime+(smarthour?3:0));
  1233.       *p2++=tbuf1; tbuf1+=40;
  1234.       if (sekunden)
  1235.         { sprintf(tbuf1,"%s",tooltypes[9]); *p2++=tbuf1; tbuf1+=40; }
  1236.       if (oval)
  1237.         { sprintf(tbuf1,"%s",tooltypes[10]); *p2++=tbuf1; tbuf1+=40; }
  1238.       if (schatten)
  1239.         { sprintf(tbuf1,"%s",tooltypes[11]); *p2++=tbuf1; tbuf1+=40; }
  1240.       if (closegad)
  1241.         { sprintf(tbuf1,"%s",tooltypes[12]); *p2++=tbuf1; tbuf1+=40; }
  1242.       sprintf(tbuf1,"%s=x",tooltypes[13]); setstr(&tbuf1[10],pens,14);
  1243.       *p2++=tbuf1; tbuf1+=40;
  1244.       sprintf(tbuf1,"%s=x",tooltypes[14]); setstr(&tbuf1[9],must,4);
  1245.       *p2++=tbuf1; *p2=NULL;
  1246.  
  1247.       p1=(UBYTE **)dobj->do_ToolTypes;
  1248.       dobj->do_ToolTypes=(char **)ttypes;
  1249.       PutDiskObject(myname,dobj);
  1250.       dobj->do_ToolTypes=(char **)p1;
  1251.  
  1252.       FreeVec(tbuf);
  1253.  
  1254.     } /* if */
  1255.  
  1256.     FreeDiskObject(dobj); dobj=NULL;
  1257.  
  1258.   } /* if */
  1259.  
  1260. } /* saveprefs */
  1261.  
  1262. void setstr(char *dest,UBYTE *sourc,int n)
  1263. { while (n--)
  1264.   { *dest++=dtox(*sourc>>4);
  1265.     *dest++=dtox(*sourc++&0xf); }
  1266. } /* setstr */
  1267.  
  1268. int dtox(int a)
  1269. { if (a>9)
  1270.     return(a+'A'-10);
  1271.   else
  1272.     return(a+'0');
  1273. } /* dtox */
  1274.  
  1275. void testifalarm(void)
  1276. { ULONG st2;
  1277.   int i,j;
  1278.  
  1279.   st2=std/5;
  1280.   if (!st2)
  1281.     st2=12;
  1282.   if (alarm && min==almin && st2==alstd)
  1283.     starttune(alarmtune);
  1284.   else if (chime && !min)
  1285.     starttune(&hourtune[smarthour?24-st2*2:22]);
  1286.   else if (chime==2)
  1287.        { for(i=6,j=min;;)
  1288.           {
  1289.             i-=2;
  1290.             if ((j-=15)<0)
  1291.               return;
  1292.             if (j==0)
  1293.               break;
  1294.           }
  1295.          starttune(&quartertune[i]);
  1296.        }
  1297. } /* testifalarm */
  1298.  
  1299. void starttune(UWORD *tune)
  1300. { ioaudio areq=audreq[0];
  1301.   if (!nosound) /* Läuft schon einer */
  1302.     return;
  1303.   areq->ioa_Request.io_Command=ADCMD_ALLOCATE;
  1304.   areq->ioa_Request.io_Message.mn_Node.ln_Pri=90; /* ALARM-Level */
  1305.   areq->ioa_Request.io_Flags=ADIOF_NOWAIT;
  1306.   areq->ioa_Data=camap;
  1307.   areq->ioa_Length=4;
  1308.   BeginIO((iorequest)areq);
  1309.   if (nosound=WaitIO((iorequest)areq))
  1310.     return;
  1311.   CopyMemQuick(areq,audreq[1],sizeof(struct IOAudio));
  1312.   playtune=tune;
  1313.   playnote();
  1314.   playnote();
  1315. } /* starttune */
  1316.  
  1317. void playnote(void)
  1318. { static int requestnr=1;
  1319.   ioaudio areq;
  1320.   requestnr=!requestnr;
  1321.   audsent[requestnr]=0;
  1322.   if (!*playtune)
  1323.   { if (!audsent[!requestnr]) /* Anderer Request auch zurück ? */
  1324.       endtune();
  1325.     return; }
  1326.   audsent[requestnr]=-1; /* Merken */
  1327.   areq=audreq[requestnr];
  1328.   areq->ioa_Request.io_Command=CMD_WRITE;
  1329.   areq->ioa_Request.io_Flags=ADIOF_PERVOL;
  1330.   areq->ioa_Data=&waveform[requestnr*4];
  1331.   areq->ioa_Length=4;
  1332.   areq->ioa_Period=500; /* ekliger Piepton */
  1333.   areq->ioa_Volume=64;
  1334.   areq->ioa_Cycles=*playtune++;
  1335.   BeginIO((iorequest)areq);
  1336. } /* playnote */
  1337.  
  1338. void endtune(void)
  1339. { ioaudio areq=audreq[0];
  1340.   areq->ioa_Request.io_Command=ADCMD_FREE;
  1341.   DoIO((iorequest)areq);
  1342.   nosound=-1;
  1343. } /* endtune */
  1344.  
  1345. #ifdef __GNUC__
  1346. #undef CreateGadgetA
  1347. ALIAS(creategadgeta,CreateGadgetA);
  1348. #if __GNUC_MINOR__ > 3
  1349. #undef AddGList
  1350. ALIAS(addglist,AddGList);
  1351. #undef EasyRequestArgs
  1352. ALIAS(easyrequestargs,EasyRequestArgs);
  1353. #endif
  1354. #endif
  1355.